﻿#include"stdafx.h"
#include"ServerDB.h"

bool ServerDB::Table_Create(vector<string>info, string db, string&msg) {
	cur_db = db.c_str();
	if (cur_db == "") {
		msg = "Please choose a database !";
		return false;
	}
	const char * tname = info[0].c_str();
	//判断表名的合法性
	CString  tbPath; tbPath = L"data\\" + cur_db + L"\\" + cur_db + L".tb";
	file.Open(tbPath, CFile::modeReadWrite | CFile::typeBinary, NULL);
	Table_Tb tb;
	while (file.Read(&tb, 1176) != 0) {
		if (strcmp(tb.name, tname) == 0) {
			msg = "Table has already exist !";
			file.Close();
			return false;
		}
	}

	int n = WideCharToMultiByte(CP_OEMCP, 0, cur_db, -1, NULL, 0, 0, FALSE);
	char* pBuff = new char[n];
	memset(pBuff, 0, n);
	WideCharToMultiByte(CP_OEMCP, 0, cur_db.GetBuffer(0), n, pBuff, n, 0, FALSE);


	Conversion(tb.name, tname);
	char temp[256];
	sprintf_s(temp, "%s%s%s%s%s", "data//", pBuff, "//", tname, ".tdf");
	Conversion(tb.tdf, temp);
	sprintf_s(temp, "%s%s%s%s%s", "data//", pBuff, "//", tname, ".tic");
	Conversion(tb.tic, temp);
	sprintf_s(temp, "%s%s%s%s%s", "data//", pBuff, "//", tname, ".trd");
	Conversion(tb.trd, temp);
	sprintf_s(temp, "%s%s%s%s%s", "data//", pBuff, "//", tname, ".tid");
	Conversion(tb.tid, temp);
	tb.crtime = CTime::GetCurrentTime();
	tb.mtime = CTime::GetCurrentTime();
	tb.fileld_num = info.size() - 1;
	tb.record_num = 0;
	file.SeekToEnd();
	file.Write(&tb, 1176);
	file.Close();
	//表名合法
	CString DBPath; CString Ctname; Ctname = tname;
	DBPath = L"data\\" + cur_db + L"\\" + Ctname;
	CString arr[] = { L".tdf",L".trd",L".tic",L".tid" };
	for (int i = 0; i < 4; i++) {
		CString path = DBPath + arr[i];
		file.Open(path, CFile::modeCreate | CFile::typeBinary, NULL);
		file.Close();
	}
	file.Open(DBPath + L".tdf", CFile::modeWrite | CFile::typeBinary, NULL);
	//写入表信息
	int pos = 0;
	for (unsigned int i = 1; i < info.size(); i++)
	{
		vector<char*> vec;
		char str[256] = { 0 };
		char *next_token = NULL, *p;
		strcpy(str, info[i].c_str());
		p = strtok_s(str, " ", &next_token);
		while (p)
		{
			vec.push_back(p);
			p = strtok_s(NULL, " ", &next_token);
		}
		Table_Tdf tdf;
		tdf.order = pos;
		tdf.mtime = CTime::GetCurrentTime();
		Conversion(tdf.name, vec[0]);
		Conversion(tdf.type, vec[1]);
		tdf.param = atoi(vec[2]);
		for (unsigned int j = 3; j < vec.size(); j++) {
			Conversion(tdf.intergrities[j - 3], vec[j]);
		}
		Conversion(tdf.intergrities[vec.size() - 3], "o");
		tdf.index = false;
		file.Write(&tdf, sizeof(tdf));
		pos += tdf.param;
	}
	file.Close();
	msg = "successful !";
	return true;
}

bool ServerDB::Table_Drop(char*name, string db, string &msg) {
	if (db == "") {
		msg = "Please choose a database !";
		return false;
	}
	cur_db = db.c_str();
	CString  tbPath; tbPath = db.c_str();
	tbPath = L"data\\" + tbPath + L"\\" + tbPath + L".tb";
	file.Open(tbPath, CFile::modeRead | CFile::typeBinary, NULL);
	Table_Tb tb; vector<Table_Tb> vec_tb;
	while (file.Read(&tb, 1176) != 0) {
		vec_tb.push_back(tb);
	}
	file.Close();

	for (unsigned int i = 0; i < vec_tb.size(); i++) {
		if (strcmp(vec_tb[i].name, name) == 0) {
			file.Remove(tbPath);
			file.Open(tbPath, CFile::modeCreate);
			file.Close();
			file.Open(tbPath, CFile::modeWrite | CFile::typeBinary, NULL);
			vec_tb.erase(vec_tb.begin() + i);
			for (unsigned int j = 0; j < vec_tb.size(); j++) {
				file.Write(&vec_tb[j], 1176);
			}
			file.Close();
			CString DBPath; CString Ctname; Ctname = name;
			DBPath = L"data\\" + cur_db + L"\\" + Ctname;

			file.Open(DBPath+L".tdf", CFile::modeRead | CFile::typeBinary, NULL);
			Table_Tdf tdf;
			while (file.Read(&tdf, sizeof(Table_Tdf))){
				if (tdf.index) {
					file.Remove(DBPath + L"_" + tdf.name+L".tid");
				}
			}
			file.Close();
			CString arr[] = { L".tdf",L".trd",L".tic",L".tid" };
			for (int a = 0; a < 4; a++) {
				file.Remove(DBPath + arr[a]);
			}
			msg = "successful !";
			return true;
		}
	}
	msg = "Incorrect table name !";
	return false;

}

bool ServerDB::Table_show(vector<string>& info, string db) {
	if (db == "" || db == "system") {
		return false;
	}
	CString  tbPath; tbPath = db.c_str();
	tbPath = L"data\\" + tbPath + L"\\" + tbPath + L".tb";
	file.Open(tbPath, CFile::modeRead | CFile::typeBinary, NULL);
	Table_Tb tb; vector<Table_Tb> vec_tb;
	while (file.Read(&tb, 1176) != 0) {
		info.push_back(tb.name);
	}
	file.Close();
	return true;
}

bool ServerDB::Table_desc(char *name, string db, string & msg) {
	cur_db = db.c_str();
	if (cur_db == "") {
		msg = "Please choose a database !";
		return false;
	}
	CString  tbPath; tbPath = L"data\\" + cur_db + L"\\" + cur_db + L".tb";
	if (!IsTable(tbPath, name)) {
		msg = "Incorrect table name !";
		return false;
	}
	CString DBPath; CString Ctname; Ctname = name;
	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".tdf";
	file.Open(DBPath, CFile::modeRead | CFile::typeBinary, NULL);
	Table_Tdf tdf;
	while (file.Read(&tdf, sizeof(tdf))) {
		CString temp;
		msg += tdf.name;
		if (strcmp(tdf.type, "4") == 0) {
			char arr[4] = { 0 }; _itoa(tdf.param, arr, 10); char tempArr[20] = "varchar(";
			strcat(tempArr, arr);
			strcat(tempArr, ")");
			temp = tempArr;
		}
		else
			temp = SimpleMap(tdf.type);
		msg = msg + " " + CStringTostring(temp);
		for (int i = 0; i < 5; i++) {
			if (strcmp(tdf.intergrities[i], "o") == 0)
				break;
			temp = SimpleMap(tdf.intergrities[i]);
			msg = msg + " " + CStringTostring(temp);
		}
		msg += "\r\n";
	}
	file.Close();
	return true;
}